home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Utilities / Workspace / PasteboardInspector / Source / PasteboardController.m < prev    next >
Text File  |  1995-06-12  |  12KB  |  512 lines

  1.  
  2. #import <appkit/Menu.h>
  3. #import <appkit/Text.h>
  4. #import <appkit/Window.h>
  5. #import <appkit/View.h>
  6. #import <appkit/ScrollView.h>
  7. #import <appkit/Pasteboard.h>
  8. #import <appkit/Application.h>
  9. #import <appkit/Listener.h>
  10. #import <appkit/Matrix.h>
  11. #import <appkit/Panel.h>
  12. #import <appkit/PopUpList.h>
  13. #import <appkit/NXImage.h>
  14. #import <appkit/NXBrowser.h>
  15. #import <appkit/NXBrowserCell.h>
  16. #import <appkit/Button.h>
  17. #import <objc/List.h>
  18. #import <appkit/NXEPSImageRep.h>
  19.  
  20. #import <soundkit/SoundView.h>
  21. #import <soundkit/Sound.h>
  22.  
  23. #import <strings.h>
  24.  
  25. #import "PasteboardController.h"
  26. #import "GCell.h"
  27. #import "PSView.h"
  28.  
  29. #define ascii 0
  30. #define rtf 1
  31. #define ps 2
  32. #define tiff 3
  33. #define snd 4
  34. #define    fname 5
  35. #define tabtext 6
  36. #define font 7
  37. #define ruler 8
  38. #define nothing 9
  39. #define unknown 10
  40.  
  41. @implementation PasteboardController
  42.  
  43. const char *titles[] = {"NXAsciiPboard", "NXRTFPboard", "NXPostScriptPboard", "NXTIFFPboard", "NXSoundPboard", "NXFilenamePboard", "NXTabularTextPboard", "NXFontPboard", "NXRulerPboard", "Nothing", "Unknown"};
  44.  
  45. - appDidInit: sender
  46. {
  47.         
  48.     [Text registerDirective:"attach" forClass: [GCell class]];
  49.     list = [menu target];
  50.     text = [textScroll docView];
  51.     rtfText = [rtfScroll docView];
  52.     tabText = [tabScroll docView];
  53.     [list setAutoupdate: YES];
  54.     unknownText = [unknownScroll docView];
  55.         
  56.     [self setupText: fontText];
  57.     [fontText setText:"NXFontPboardType"];
  58.     
  59.     [self setupText: fnameText];
  60.     
  61.     [self setupText: rulerText];
  62.     [rulerText toggleRuler: self];
  63.     [rulerText setText: "NXRulerPBoardType"];
  64.     
  65.     [[NXApp appListener] setServicesDelegate: self];
  66.     [browser setMinColumnWidth:0];
  67.     [browser setMaxVisibleColumns:1];
  68.     pasteboardList = [[List alloc] init];
  69.     [pasteboardList addObject:[Pasteboard newName:NXSelectionPboard]];
  70.     [pasteboardList addObject:[Pasteboard newName:NXFontPboard]];
  71.     [pasteboardList addObject:[Pasteboard newName:NXRulerPboard]];
  72.     [pasteboardList addObject:[Pasteboard newName:NXFindPboard]];
  73.     [browser setAction: @selector(setPasteboard:)];
  74.     [browser setDoubleAction: @selector(setPasteboard:)];
  75.     viewList = [[List alloc] init];
  76.     [viewList addObject: textView];
  77.     [viewList addObject: rtfView];
  78.     [viewList addObject: epsView];
  79.     [viewList addObject: graphicView];
  80.     [viewList addObject: soundView];
  81.     [viewList addObject: fileView];
  82.     [viewList addObject: tabView];
  83.     [viewList addObject: fontView];
  84.     [viewList addObject: rulerView];
  85.     [viewList addObject: nothingView];
  86.     [viewList addObject: unknownView];
  87.     [browser loadColumnZero];
  88.     [[browser matrixInColumn: 0] selectCellAt: 0 : 0];
  89.     [self getPasteboard:[pasteboardList objectAt:0]];
  90.     
  91.     return self;
  92. }
  93.  
  94. - setPasteboard: sender
  95. {
  96.         [self getPasteboard:[pasteboardList objectAt:[[browser matrixInColumn: 0] selectedRow]]];
  97.         
  98.         return self;
  99. }
  100.  
  101. - (int)browser: sender fillMatrix: matrix inColumn: (int)column
  102. {
  103.     int i, row, col;
  104.     
  105.     for(i = 0; i < [pasteboardList count]; i++)
  106.     {
  107.         [matrix addRow];
  108.         [[matrix cellAt: i : 0] setStringValue:[[pasteboardList objectAt:i] name]];
  109.         [[matrix cellAt: i : 0] setLeaf: YES];
  110.         [[matrix cellAt: i : 0] setLoaded: YES];
  111.     }
  112.     
  113.     [matrix getNumRows:&row numCols:&col];
  114.     return row;
  115. }
  116.  
  117. - windowWillResize: sender toSize: (NXSize *) frameSize
  118. {
  119.     if(frameSize->width <= 268)
  120.         frameSize->width = 268;
  121.     if(frameSize->height <= 400)
  122.         frameSize->height = 400;
  123.         
  124.     return self;
  125. }
  126.         
  127. - getPasteboard: (id) pasteboard userData: (const char *)userData error: (char **) msg
  128. {
  129.     NXRect r;
  130.     
  131.     [browser getFrame:&r];
  132.     [[pasteboardWindow contentView] replaceSubview: browser with: examineView];
  133.     [examineView setFrame:&r];
  134.     [examineView display];
  135.     [pasteboardWindow flushWindow];
  136.     [self getPasteboard:pasteboard];
  137.     
  138.     return self;
  139. }
  140.  
  141. - setupText: txt
  142. {
  143.     NXSize aSize = {1.0E38,1.0E38};
  144.     NXRect r;
  145.  
  146.     [[txt superview] getFrame: &r];
  147.     [txt setMonoFont: NO];
  148.     [txt setVertResizable:YES];
  149.     [txt setHorizResizable:YES];
  150.     [txt setOpaque:YES];
  151.     [txt setMinSize:&r.size];
  152.     [txt setMaxSize:&aSize];
  153.     
  154.     return self;
  155. }
  156.  
  157. - switchBoxes:sender
  158. {
  159.     NXRect r;
  160.     
  161.     [curView getFrame: &r];
  162.     [[pasteboardWindow contentView] replaceSubview: curView
  163.                                     with:[viewList objectAt:[[list itemList] selectedTag]]];
  164.     curView = [viewList objectAt:[[list itemList] selectedTag]];
  165.     [pasteboardWindow setTitle: titles[[[list itemList] selectedTag]]];
  166.     [curView setFrame: &r];    
  167.  
  168.     if([[list itemList] selectedTag] == unknown)
  169.     {
  170.         NXStream *stream;
  171.         char *data;
  172.         int len;
  173.         
  174.         if(![self     check:[[pasteboardList objectAt:[[browser matrixInColumn:0] selectedRow]] readType:[[[list itemList] selectedCell] title]
  175.                     data:&data
  176.                     length: &len]])
  177.                 return self;
  178.         stream = NXOpenMemory(data, len, NX_READONLY);
  179.         NXSeek(stream, 0, NX_FROMSTART);
  180.         [unknownText readText: stream];
  181.         NXClose(stream);
  182.     }
  183.     [[pasteboardWindow contentView] display];
  184.     [pasteboardWindow flushWindow];
  185.     return self;
  186. }
  187.  
  188.  
  189. - getPasteboard:pb
  190. {
  191.     char *const *s;
  192.     char *const *types;
  193.     int i;
  194.     id cell;
  195.     int ct = 0;
  196.     
  197.     for(i = 0; i < [list count]; i++)
  198.     {
  199.         [list removeItemAt:0];
  200.     }
  201.     
  202.     [menu setTitle:titles[nothing]];
  203.     
  204.     types = [pb types];
  205.     
  206.     for(s = types; *s; s++)
  207.     {
  208.         if (!strcmp(*s, NXAsciiPboardType))
  209.         {
  210.             [self addMenuItem: ascii : pb];
  211.             ct++;
  212.         }
  213.         else
  214.         if (!strcmp(*s, NXRTFPboardType))
  215.         {
  216.             [self addMenuItem: rtf: pb];
  217.             ct++;
  218.         }
  219.         else
  220.         if (!strcmp(*s, NXPostScriptPboardType))
  221.         {
  222.             [self addMenuItem: ps: pb];
  223.             ct++;
  224.         }
  225.         else
  226.         if (!strcmp(*s, NXTIFFPboardType))
  227.         {
  228.             [self addMenuItem: tiff: pb];
  229.             ct++;
  230.         }
  231.         else
  232.         if (!strcmp(*s, NXSoundPboardType))
  233.         {
  234.             [self addMenuItem: snd: pb];
  235.             ct++;
  236.         }
  237.         else
  238.         if (!strcmp(*s,  NXFilenamePboardType))
  239.         {
  240.             [self addMenuItem: fname: pb];
  241.             ct++;
  242.         }
  243.         else
  244.         if (!strcmp(*s, NXTabularTextPboardType))
  245.         {
  246.             [self addMenuItem: tabtext: pb];
  247.             ct++;
  248.         }
  249.         else
  250.         if (!strcmp(*s, NXFontPboardType))
  251.         {
  252.             [self addMenuItem: font: pb];
  253.             ct++;
  254.         }
  255.         else
  256.         if (!strcmp(*s, NXRulerPboardType))
  257.         {
  258.             [self addMenuItem: ruler: pb];
  259.             ct++;
  260.         }
  261.         else
  262.         if(NX_NOT_IN_LIST != [pasteboardList indexOf:pb])
  263.         {
  264.             cell = [list addItem: *s action: @selector(switchBoxes:) keyEquivalent: 0];
  265.             [cell setTag: unknown];
  266.             [menu setTitle:*s];
  267.             [[list itemList] selectCellWithTag:unknown];
  268.             ct++;
  269.         }
  270.     }
  271.                 
  272.     if(ct == 0)
  273.     {
  274.         cell = [list addItem: titles[nothing] action: @selector(switchBoxes:) keyEquivalent: 0];
  275.         [cell setTag: nothing];
  276.         [menu setTitle:titles[nothing]];
  277.         [[list itemList] selectCellWithTag:nothing];
  278.     }
  279.     
  280.     [self switchBoxes: self];
  281.         
  282.     return self;
  283. }
  284.  
  285. - addMenuItem: (int) type : pb
  286. {
  287.     id cell;
  288.     char *data;
  289.     int len;
  290.     NXStream *stream;
  291.     NXRect r;
  292.     [curView getFrame:&r];
  293.     
  294.     if([list indexOfItem:titles[type]] == -1)
  295.     {
  296.         cell = [list addItem: titles[type] action: @selector(switchBoxes:) keyEquivalent: 0];
  297.         [cell setTag: type];
  298.         [menu setTitle:titles[type]];
  299.         [[list itemList] selectCellWithTag:type];
  300.     }
  301.  
  302.     switch([[list itemList] selectedTag])
  303.     {
  304.         case ascii :
  305.             if(![self check:[pb     readType:NXAsciiPboardType
  306.                         data:&data
  307.                         length: &len]])
  308.                 return self;
  309.             data[len] = '\0';
  310.             [textView setFrame:&r];
  311.             [text setText: data];
  312.             break;
  313.         case rtf :
  314.             if(![self check:[pb     readType:NXRTFPboardType
  315.                         data:&data
  316.                         length: &len]])
  317.                 return self;
  318.             data[len] = '\0';
  319.             stream = NXOpenMemory(data, len, NX_READONLY);
  320.             [rtfView setFrame:&r];
  321.             [rtfText readRichText: stream];
  322.             break;
  323.         case ps : 
  324.              if(![self check:[pb     readType:NXPostScriptPboardType
  325.                         data:&data
  326.                         length: &len]])
  327.                 return self;
  328.             stream = NXOpenMemory(data, len, NX_READONLY);
  329.             [epsView setFrame:&r];
  330.             [eps setImage: [[NXImage alloc] initFromStream: stream]];
  331.             break;
  332.         case tiff : 
  333.              if(![self check:[pb     readType:NXTIFFPboardType
  334.                         data:&data
  335.                         length: &len]])
  336.                 return self;
  337.             stream = NXOpenMemory(data, len, NX_READONLY);
  338.             [graphicView setFrame:&r];
  339.             [graphic setImage: [[NXImage alloc] initFromStream: stream]];
  340.             NXClose(stream);
  341.             break;
  342.         case snd : 
  343.             [soundView setFrame:&r];
  344.             [sound    setSound: [Sound newFromPasteboard]];
  345.             break;
  346.         case fname :
  347.         {
  348.             char *tab;
  349.              if(![self check:[pb     readType:NXFilenamePboardType
  350.                         data:&data
  351.                         length: &len]])
  352.                 return self;
  353.             [fileView setFrame:&r];
  354.             while(data)
  355.             {
  356.                 tab = strchr(data, '\t');
  357.                 if (tab) *tab = '\0';
  358.                 [fnameText     setSel: [fnameText textLength]
  359.                             : [fnameText textLength]];
  360.                 [fnameText replaceSelWithCell: [[GCell alloc] initFromFile: data]];
  361.  
  362.                    data = tab ? ++tab : NULL;
  363.             }
  364.             break;
  365.         }
  366.         case tabtext :
  367.             if(![self check:[pb     readType:NXTabularTextPboardType
  368.                         data:&data
  369.                         length: &len]])
  370.                 return self;
  371.             data[len] = '\0';
  372.             [tabView setFrame:&r];
  373.             [tabText setText: data];
  374.             break;
  375.         case font :
  376.             [fontView setFrame:&r];
  377.             [fontText setSel: 0 : [fontText textLength]];
  378.             [fontText pasteFont: self];
  379.             break;
  380.         case ruler :
  381.             [rulerView setFrame:&r];
  382.             [rulerText setSel: 0 : [rulerText textLength]];
  383.             [rulerText pasteRuler: self];
  384.             break;
  385.         case nothing :
  386.         default :
  387.             break;
  388.     }
  389.         
  390.     return self;
  391. }
  392.  
  393. - (int)check: pb
  394. {
  395.     if(!pb)
  396.     {
  397.         if(NXRunAlertPanel(NULL, "The type you requested is not currently on the pasteboard. Would you like to update the pasteboard menu?", "Yes", "No", NULL) == NX_ALERTDEFAULT)
  398.         {
  399.             [self getPasteboard:[pasteboardList objectAt:[[browser matrixInColumn: 0] selectedRow]]];
  400.         }
  401.         return NO;
  402.     }
  403.     else
  404.         return YES;
  405. }
  406.  
  407. - done: sender
  408. {
  409.     [self perform:@selector(done) with:self afterDelay:5 cancelPrevious:YES];
  410.     return self;
  411. }
  412.  
  413. - done
  414. {
  415.     NXRect r;
  416.     [examineView getFrame:&r];
  417.     [[pasteboardWindow contentView] replaceSubview: examineView with: browser];
  418.     [browser setFrame:&r];
  419.     [browser display];
  420.     [pasteboardWindow flushWindow];
  421.     [self getPasteboard:[pasteboardList objectAt:[[browser matrixInColumn: 0] selectedRow]]];
  422.     
  423.     return self;
  424. }
  425.  
  426. - putBack: sender
  427. {
  428.     char *data;
  429.     NXStream *stream;   
  430.     const char *types[1];
  431.     int length, maxlen;
  432.     id pboard = [Pasteboard new];
  433.     
  434.     switch([[list itemList] selectedTag])
  435.     {
  436.         case ascii :
  437.             [text selectAll: self];
  438.             [text copy: self];
  439.             break;
  440.         case rtf :
  441.             [rtfText selectAll: self];
  442.             [rtfText copy: self];
  443.             break;
  444.         case ps :
  445.         {
  446.             id image = [eps getImage];
  447.             id rep = [image bestRepresentation];
  448.             [rep getEPS: &data length:&length];
  449.             types[0] = NXPostScriptPboardType;
  450.             [pboard declareTypes:types num:1 owner:[self class]];
  451.             [pboard writeType:types[0] data:data length:length];
  452.             break;
  453.         }
  454.         case tiff :
  455.         {
  456.             id image = [graphic getImage];
  457.             id rep = [image bestRepresentation];
  458.             stream = NXOpenMemory(NULL, 0, NX_READWRITE);
  459.             [rep writeTIFF:stream];
  460.             NXGetMemoryBuffer(stream, &data, &length, &maxlen);
  461.             types[0] = NXTIFFPboardType;
  462.             [pboard declareTypes:types num:1 owner:[self class]];
  463.             [pboard writeType:types[0] data:data length:length];
  464.             NXClose(stream);            
  465.             break;
  466.         }
  467.         case snd :
  468.             [sound selectAll:self];
  469.             [sound copy:self];
  470.             break;
  471.         case fname :
  472.             types[0] = NXFilenamePboardType;
  473.             [pboard declareTypes:types num:1 owner:[self class]];
  474.             break;
  475.         case tabtext :
  476.             types[0] = NXTabularTextPboardType;
  477.             stream = NXOpenMemory(NULL, 0, NX_READWRITE);
  478.             [tabText writeText: stream];
  479.             NXSeek(stream, 0, NX_FROMSTART);
  480.             NXGetMemoryBuffer(stream, &data, &length, &maxlen);
  481.             [pboard writeType:types[0] data:data length:length];
  482.             NXClose(stream);            
  483.             break;
  484.         case font :
  485.             [fontText selectAll: self];
  486.             [fontText copyFont:self];
  487.             break;
  488.         case ruler :
  489.             [rulerText selectAll: self];
  490.             [rulerText copyRuler:self];
  491.             break;
  492.         case nothing :
  493.             break;
  494.         case unknown :
  495.             types[0] = [[[list itemList] selectedCell] title];
  496.             [pboard declareTypes:types num:1 owner:[self class]];
  497.             stream = NXOpenMemory(NULL, 0, NX_READWRITE);
  498.             [unknownText writeText: stream];
  499.             NXSeek(stream, 0, NX_FROMSTART);
  500.             NXGetMemoryBuffer(stream, &data, &length, &maxlen);
  501.             [pboard writeType:types[0] data:data length:length];
  502.             NXClose(stream);            
  503.             break;
  504.         default:
  505.             break;
  506.     }
  507.     
  508.     return self;
  509. }
  510.  
  511. @end
  512.